#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
using namespace std;

#include "Event.h"
#include "Game.h"
#include "Team.h"
#include "Shot.h"
#include "Time.h"
#include "Player.h"
#include "Foul.h"
#include "Violation.h"
#include "Rebound.h"
#include "Timeout.h"
#include "Jumpball.h"
#include "Steal.h"
#include "Newlineup.h"

enum possibleTeams {HOME=0, AWAY=1};
const int ALL_PLAYERS=999;

Game::Game()
{	
teams[AWAY].setName("AWAY");
teams[HOME].setName("HOME");
addLineup();
//set default beginning players
Event *start;
start=new Newlineup;
int defualtStartingPlayers[5]={1,2,3,4,5};
Time firstTime(1,12,60);  
*start=Newlineup(firstTime,defualtStartingPlayers);

teams[HOME].addTeamEvent(start);
teams[AWAY].addTeamEvent(start);
//As a defualt, assume the teams[0] team starts with possession of the ball
teams[HOME].setPossess(true); 
teams[AWAY].setPossess(false);


}



void Game::getInput(bool isTestingMode)
{
ifstream data;
	if (isTestingMode)
	{	
	data.open("data1.txt");
	}
Event* ptr=NULL,*lastEvent=NULL;
bool possess,bogus;
bool goodValueInput=false,validEventType=false;
string type=" ";



int commitTeam=-1,oppTeam=-1;



		
	cin>>type;
	
	while((type!="q")&&(type!="Q")) 
	{
	goodValueInput=false;

		if ((type=="stats")||(type=="STATS")) ///explore possibile checking for inconsistant capitolization
		{
		displayLiveStats();
		validEventType=false;
		}
		else if (type=="SH")
		{	
	 	ptr=new Shot;	
		validEventType=true;
		}
		else if (type=="F")
		{	
		ptr=new Foul;
		validEventType=true;
		}
		else if (type=="V")
		{	
		ptr=new Violation;
		validEventType=true;
		}
		else if (type=="RB")
		{
		ptr=new Rebound;	
		validEventType=true;
		}
		else if (type=="ST")
		{
		ptr=new Steal;	
		validEventType=true;	
		}	
		else if (type=="TO") //warning. addTime may not be defined for this
		{
		ptr=new Timeout;	
		validEventType=true;	
		}
		else if (type=="JB")
		{		
		ptr=new Jumpball;	
		validEventType=true;	
		}		
		else if (type=="NL")
		{		
		ptr=new Newlineup;	
		validEventType=true;			
		}
		else
		{	
		cin.clear();
		cin.ignore(std::numeric_limits<streamsize>::max(),'\n');
		cout<<"Enter another event or q to quit"<<endl;
		validEventType=false;			
		}
		
		if (validEventType)
		goodValueInput=ptr->assignValues();  
	
		if (goodValueInput && validEventType)				//if the input was good. now we dont have to worry about team types. 
		{
			if (((ptr->getTeam()) == 'H')||((ptr->getTeam()) == 'h'))
			{
			commitTeam=HOME;
			oppTeam=AWAY;
			}
			else if (((ptr->getTeam()) == 'A')||((ptr->getTeam()) == 'a'))				
			{
			commitTeam=AWAY;
			oppTeam=HOME;
			}
			teams[commitTeam].addTeamEvent(ptr);
			bogus=teams[oppTeam].addTime(ptr);
			possess=teams[commitTeam].addTime(ptr);
			teams[oppTeam].setPossess(!possess);	
			endGameTime=ptr->getTime();
			showScoreBoard();
					
			}	
	
		cin>>type;
			
	}
	

}

//This function shows the final score for both teams 
void Game::displayFinalScore(bool isTestingMode)
{
cout<<"---------------------------FINAL SCORE---------------------------------------------"<<endl;
cout<<"home: "<<teams[HOME].getPoints()<<endl;
cout<<"away: "<<teams[AWAY].getPoints()<<endl;

}
//This function return the current score for the desired team
int Game::getPoints(string TeamName)
{
	if ((TeamName=="AWAY")||(TeamName=="away"))
	{
	return teams[AWAY].getPoints();
	}
	else if ((TeamName=="HOME")||(TeamName=="home"))
	{
	return teams[HOME].getPoints();
	}
//else no result, invalid team
}
 
void Game::displayScoreByPeriod()
{
cout<<"--------------------------Points by Period-----------------------------------------"<<endl;
int maxPeriod=endGameTime.getPeriod();
if (maxPeriod<4) //account for overtime periods
maxPeriod=4;
	for (int period=1;period<=maxPeriod;period++)
	{
	cout<<"Period: "<<period;
	teams[HOME].displayPointsByPer(period);
	teams[AWAY].displayPointsByPer(period);
	}
cout<<endl;
}	




void Game::displayFoulsPerTeam()
{

cout<<"-------------------------Fouls Per Team---------------------------------------------"<<endl;
cout<<teams[HOME].getName()<<":"<<teams[HOME].getFouls(ALL_PLAYERS)<<"  "<<teams[AWAY].getName()<<":"<<teams[AWAY].getFouls(ALL_PLAYERS)<<endl;

}

void Game::displayVioPerTeam()
{

cout<<"-------------------------Violations Per Team-----------------------------------------"<<endl;
cout<<teams[HOME].getName()<<":"<<(teams[HOME].getViolations())<<"  "<<teams[AWAY].getName()<<":"<<(teams[AWAY].getViolations())<<endl;

}

void Game::displayFTPercents()
{

cout<<"-----------------Free Throw Percents By Team-----------------------------------------"<<endl;
cout<<teams[HOME].getName()<<":"<<(teams[HOME].getShotPercent(1))<<"  "<<teams[AWAY].getName()<<":"<<(teams[AWAY].getShotPercent(1))<<endl;

}

void Game::displayPossessionTime()
{

cout<<"------------------Possession Time by Team--------------------------------------------"<<endl;
Time tempTime;
tempTime=teams[HOME].getPossessionStartTo(endGameTime);
cout<<teams[HOME].getName()<<tempTime;
tempTime=teams[AWAY].getPossessionStartTo(endGameTime);
cout<<teams[AWAY].getName()<<tempTime<<endl;

}


void Game::addLineup()
{

for (int i=0;i<2;i++)
	{
	teams[i].addPlayer(1,"One");
	teams[i].addPlayer(2,"Two");
	teams[i].addPlayer(3,"Three");
	teams[i].addPlayer(4,"Four");
	teams[i].addPlayer(5,"Five");
	teams[i].addPlayer(6,"Six");
	teams[i].addPlayer(7,"Seven");
	teams[i].addPlayer(8,"Eight");
	teams[i].addPlayer(9,"Nine");
	teams[i].addPlayer(10,"Ten");
	teams[i].addPlayer(11,"Eleven");
	teams[i].addPlayer(12,"Twelve");
	teams[i].addPlayer(13,"Thirteen");
	teams[i].addPlayer(14,"Fourteen");
	teams[i].addPlayer(15,"Fifteen");
	}
}

void Game::showScoreBoard()
{
//show scores, fouls, bonus status, current Time
displayFinalScore(0);
displayFoulsPerTeam();
displayBonus();
cout<<"Current Time: "<<endGameTime<<endl;
cout<<"Possesion : ";
if (teams[HOME].getPossess())
cout<<teams[HOME].getName()<<endl;
else if (teams[AWAY].getPossess())
cout<<teams[AWAY].getName()<<endl;
else
cout<<"LOOSE BALL!"<<endl;

}

void Game::displayBonus()
{
cout<<"Bonus Status (extra shots granted per foul)"<<setw(6)<<teams[HOME].getName()<<" : "<<teams[HOME].getBonus(endGameTime.getPeriod())<<"  "<<
	teams[AWAY].getName()<<" : "<<teams[AWAY].getBonus(endGameTime.getPeriod())<<endl;
}

void Game::displayLiveStats()
{
/*- All the information you normally report for the scoreboard.
- For each player on each team, report:  name, number, fouls, rebounds, steals, 2-pointers attempted, 2-pointers made, 2-pointer percentage made, same for 3-pointers, and the same for free throws. 
*/

showScoreBoard();
teams[HOME].showLiveStats();
teams[AWAY].showLiveStats();
}


void Game::checkTrends()
{
string toReport;
ofstream trendReport;
trendReport.open("TrendReport.txt");
//check for open
toReport=teams[AWAY].checkUpcomingFTShooter();
toReport=teams[HOME].checkUpcomingFTShooter();
trendReport<<toReport;

}


